from threading import Thread, Lock
import time
from .cv_image import add_detectedlane_image,add_object_feature_image,detect_red_object,detect_rectangle,detect_yellow_flower,detect_circles
from .cv_image_controller import  ObstacleDetector
from .cv_enhanced_vision_controller import EnhancedVisionCarController

from picamera2 import Picamera2

class CameraStream:
    OPENCV_NONE=0 
    OPENCV_LANE=1 
    OPENCV_OBJECT_FEATURE=2 
    OPENCV_OBJECT_RED=3 
    OPENCV_OBJECT_RECTANGLE=4 
    OPENCV_YELLOW_FLOWER=5
    OPENCV_OBJECT_CIRCLE=6
    OPENCV_OBSTACLE_DETECTOR=7
    OPENCV_ENHANCED_VISION=8    
    
    def __init__(self, src=0):
        self.picam2 = Picamera2()
        self.picam2.configure(self.picam2.create_preview_configuration(main={"format": 'XRGB8888', "size": (1024,768)}))
        self.picam2.start()
        self.frame = self.picam2.capture_array()
        
        self.started = False
        self.read_lock = Lock()
        self.cur_opencv_action= CameraStream.OPENCV_NONE

    def start(self):
        if self.started:
            print("already started!!")
            return None
        self.started = True
        self.thread = Thread(target=self.update)
        self.daemon=True
        self.thread.start()
        return self

    def update(self):
        obs_detector=ObstacleDetector()
        enhanced_vision_controller=EnhancedVisionCarController()
        while self.started:
            time.sleep(0.033) # 30fps
            frame = self.picam2.capture_array()
        
            #  import the opencv mothods to process the image from opencv_image 
            result=frame
            if self.cur_opencv_action==CameraStream.OPENCV_LANE:
                result=add_detectedlane_image(result)
            elif self.cur_opencv_action==CameraStream.OPENCV_OBJECT_RED:
                result=detect_red_object(result)
            elif self.cur_opencv_action==CameraStream.OPENCV_OBJECT_RECTANGLE:
                result=detect_rectangle(result)
            elif self.cur_opencv_action==CameraStream.OPENCV_OBJECT_CIRCLE:
                result=detect_circles(result)
            elif self.cur_opencv_action==CameraStream.OPENCV_YELLOW_FLOWER:
                result=detect_yellow_flower(result)    
            elif self.cur_opencv_action==CameraStream.OPENCV_OBSTACLE_DETECTOR:
                result= obs_detector.process_frame(result)   
            elif self.cur_opencv_action==CameraStream.OPENCV_ENHANCED_VISION:
                result=  enhanced_vision_controller.process_frame(result)       
            elif self.cur_opencv_action==CameraStream.OPENCV_NONE:
                result=result
            self.read_lock.acquire()
            self.frame = result
            self.read_lock.release()

    def read(self):
        self.read_lock.acquire()
        frame = self.frame.copy()
        self.read_lock.release()
        return frame

    def stop(self):
        self.started = False
        self.thread.join()

    def __exit__(self, exc_type, exc_value, traceback):
        self.picam2.stop()
        